home *** CD-ROM | disk | FTP | other *** search
Wrap
// BEGIN FLOCK GPL // // Copyright Flock Inc. 2005-2007 // http://flock.com // // This file may be used under the terms of of the // GNU General Public License Version 2 or later (the "GPL"), // http://www.gnu.org/licenses/gpl.html // // Software distributed under the License is distributed on an "AS IS" basis, // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License // for the specific language governing rights and limitations under the // License. // // END FLOCK GPL // const Cc = Components.classes; const Ci = Components.interfaces; const FLOCK_MW_CID = Components.ID('{143c7ec8-6ae9-473a-9289-e19321bfa72e}'); const FLOCK_MW_CONTRACTID = '@flock.com/blog/service/metaweblog;1'; const FLOCK_MW_DESCRIPTION = 'MetaWeblog'; const FLOCK_BLOG_RDF_SETTINGS = 'urn:flock:blog:settings'; function loadLibraryFromSpec(aSpec) { var loader = Components.classes['@mozilla.org/moz/jssubscript-loader;1'] .getService(Components.interfaces.mozIJSSubScriptLoader); loader.loadSubScript(aSpec); } loadLibraryFromSpec("chrome://browser/content/flock/blog/technoratiTags.js"); loadLibraryFromSpec("chrome://browser/content/flock/blog/blogBackendLib.js"); loadLibraryFromSpec("chrome://browser/content/flock/xmlrpc/xmlrpchelper.js"); // CONSTRUCTOR function metaweblogWebService () { //this.mQueue = null; // set attributes this.name = 'MetaWeblog'; this.shortName = 'metaweblog'; this.description = "The MetaWeblog API" this.supportsCategories = 2; this.supportsPostReplace = true; this.appKey = ""; // Logger this.logger = Components.classes['@flock.com/logger;1'] .createInstance(Components.interfaces.flockILogger); this.logger.init("blog"); } // the nsISupports implementation metaweblogWebService.prototype.QueryInterface = function (iid) { if (iid.equals(Ci.flockICustomBlogWebService) || iid.equals(Ci.flockIBlogWebService) || iid.equals(Ci.flockIWebService) || iid.equals(Ci.nsIClassInfo) || iid.equals(Ci.nsISupports)) { return this; } throw Components.results.NS_ERROR_NO_INTERFACE; } // PRIVATE METHODS function unescapeXML(aString) { var result = aString; result = result.replace(/*34;/, '"'); result = result.replace(/*38;/, '&'); result = result.replace(/*39;/, "'"); result = result.replace(/*60;/, "<"); result = result.replace(/*62;/, ">"); result = result.replace(/ /, " "); result = result.replace(//, "-"); return result; } metaweblogWebService.prototype.xmlrpc = function() { var listener = arguments[0]; var url = arguments[1]; var call = arguments[2]; var params = new Array(); for(var i=3;i<arguments.length;++i) { params[params.length] = arguments[i]; } var rpc = new JSXMLRPC(); var logMessage = ">>>>>>>>>> MetaWeblog API: FLOCK TO SERVER\n"; logMessage += " URL: " + url + "\n"; logMessage += " CALL: " + call + "\n"; for (i in params) logMessage += " params["+i+"] = "+params[i]+"\n"; this.logger.info(logMessage); rpc.call(listener, url, call, params); } // Listeners function blogListener(aListener, aBool){ this.listener = aListener; this.container = aBool; this.logger = Components.classes['@flock.com/logger;1'] .createInstance(Components.interfaces.flockILogger); this.logger.init("blog"); } blogListener.prototype = { // aResult is an Array of struct objects onResult: function(aResult) { this.logger.info("<<<<<<<<<< MetaWeblog API: SERVER TO FLOCK\n"); for (i=0; i<aResult.length; i++){ this.logger.debug("Entry\n"); var entry = aResult[i]; for (j in entry) this.logger.debug(" -> "+j+": "+entry[j]+"\n"); } // Create an in-memory datasource var rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"] .getService(Components.interfaces.nsIRDFService); var rdf = Components.classes["@mozilla.org/rdf/datasource;1?name=in-memory-datasource"].createInstance(Components.interfaces.nsIRDFDataSource); var rdfContainerUtils = Components.classes["@mozilla.org/rdf/container-utils;1"] .getService(Components.interfaces.nsIRDFContainerUtils); // Fill it with the results if (this.container) var container = rdfContainerUtils.MakeSeq(rdf, rdfService.GetResource("urn:flock:blog:elements")); for (i=0; i<aResult.length; i++){ var id='obj_' + Math.round(10000*Math.random()) var subject = rdfService.GetResource("http://www.flock.com/rdf/"+id); var entry = aResult[i]; for (j in entry){ var predicate = rdfService.GetResource("http://www.flock.com/rdf/"+j); //if (typeof entry[j] == 'string') // entry[j] = unescapeXML(entry[j]); var name = rdfService.GetLiteral(entry[j]); rdf.Assert(subject, predicate, name, true); } if (this.container) container.AppendElement(subject); } // and return the data source through the listener this.listener.onResult(rdf); }, onError: function(error) { this.logger.error("<<<<<<<<<< MetaWeblog API: SERVER TO FLOCK\n"); this.logger.error("ERROR "+error+"\n"); this.listener.onError(error); }, onFault: function(error) { this.logger.error("<<<<<<<<<< MetaWeblog API: SERVER TO FLOCK\n"); this.logger.error("FAULT "+error+"\n"); this.listener.onFault(error); } } function blogCategoryListener(aListener, aBool){ this.listener = aListener; this.container = aBool; this.logger = Cc['@flock.com/logger;1'] .createInstance(Ci.flockILogger); this.logger.init("blog"); } blogCategoryListener.prototype = { onResult: function(aResult) { this.logger.info("<<<<<<<<<< Metaweblog API: SERVER TO FLOCK\n"); var result = new Array(); for (i=0; i<aResult.length; i++){ this.logger.debug("Entry\n"); var entry = aResult[i]; for (j in entry) this.logger.debug(" -> "+j+": "+entry[j]+"\n"); } for (i=0; i<aResult.length; i++){ this.logger.debug("Found the category "+aResult[i].description+"\n"); var category = new BlogCategory(i, aResult[i].description); result.push(category); } // and return the data source through the listener this.listener.onResult(new simpleEnumerator(result)); }, onError: function(errorcode, errormsg) { this.logger.error("<<<<<<<<<< Metaweblog API: SERVER TO FLOCK\n"); this.logger.error("ERROR "+errorcode+" "+errormsg+"\n"); var error = Cc['@flock.com/error;1'].createInstance(Ci.flockIError); error.serviceErrorCode = errorcode; error.serviceErrorString = errormsg; this.listener.onError(error); }, onFault: function(errorcode, errormsg) { this.logger.error("<<<<<<<<<< Metaweblog API: SERVER TO FLOCK\n"); this.logger.error("FAULT "+errorcode+" "+errormsg+"\n"); var error = Cc['@flock.com/error;1'].createInstance(Ci.flockIError); error.serviceErrorCode = errorcode; error.serviceErrorString = errormsg; this.listener.onFault(error); } } metaweblogWebService.prototype.detectAccount = function (aUrl, aLinkList){ return null; } metaweblogWebService.prototype.newPost = function(aListener, aBlogId, aPost, aPublish, aNotifications){ var gBlogService = Cc['@flock.com/flock-blog;1'].getService(Ci.flockIBlogService); var account = gBlogService.getAccount(aBlogId); var svc = this; var notifsArray = []; var catArray = []; var html = aPost.description + addTechnoratiTags(aPost.tags); while (aPost.categories.hasMoreElements()) { var category = aPost.categories.getNext(); category.QueryInterface(Ci.flockIBlogCategory); catArray.push(category.label); } var listener = { onResult: function(aResult) { aListener.onResult(aResult); }, onError: function(error) { svc.logger.error("<<<<<<<<<< MetaWeblog API: SERVER TO FLOCK\n"); svc.logger.error("ERROR "+error+"\n"); aListener.onError(error); }, onFault: function(error) { svc.logger.error("<<<<<<<<<< MetaWeblog API: SERVER TO FLOCK\n"); svc.logger.error("FAULT "+error+"\n"); aListener.onFault(error); } }; var xmlrpcServer = new flockXmlRpcServer (account.apiLink); var args = [account.blogid, account.username, account.password, {title: aPost.title, description: html, categories: catArray, mt_convert_breaks: "", mt_tb_ping_urls: notifsArray}, aPublish]; xmlrpcServer.call("metaWeblog.newPost", args, listener); } metaweblogWebService.prototype.editPost = function(aListener, aBlogId, aPost, aPublish, aNotifications){ var gBlogService = Cc['@flock.com/flock-blog;1'].getService(Ci.flockIBlogService); var account = gBlogService.getAccount(aBlogId); var catArray = []; var svc = this; var listener = { onResult: function(aResult) { aListener.onResult(aResult); }, onError: function(error) { svc.logger.error("<<<<<<<<<< MetaWeblog API: SERVER TO FLOCK\n"); svc.logger.error("ERROR "+error+"\n"); aListener.onError(error); }, onFault: function(error) { svc.logger.error("<<<<<<<<<< MetaWeblog API: SERVER TO FLOCK\n"); svc.logger.error("FAULT "+error+"\n"); aListener.onFault(error); } }; var notifsArray = new Array(); var html = aPost.description + addTechnoratiTags(aPost.tags); while (aPost.categories.hasMoreElements()) { var category = aPost.categories.getNext(); category.QueryInterface(Ci.flockIBlogCategory); catArray.push(category.label); } var xmlrpcServer = new flockXmlRpcServer (account.apiLink); var args = [aPost.postid, account.username, account.password, {title: aPost.title, description: html, categories: catArray, dateCreated: new Date(parseInt(aPost.issued))}, aPublish]; xmlrpcServer.call("metaWeblog.editPost", args, listener); } metaweblogWebService.prototype.deletePost = function(aListener, aAccount, aPostid){ dump("***** metaweblogWebService.deletePost: not supported!\n"); } metaweblogWebService.prototype.getPost = function(aListener, aAccount, aPostid){ var listener = new blogListener(aListener, false); var xmlrpcServer = new flockXmlRpcServer (aAccount.apiLink); var args = [aPostid, aAccount.username, aAccount.password]; xmlrpcServer.call("metaWeblog.getPost", args, listener); } metaweblogWebService.prototype.getUsersBlogs = function(aListener, aAccount){ var svc = this; var listener = { // aResult is an Array of struct objects onResult: function(aResult) { var result = new Array(); for (i=0; i<aResult.length; i++){ var entry = aResult[i]; var newAccount = new BlogAccount(entry.blogName); newAccount.blogid = entry.blogid; newAccount.apiLink = ""; newAccount.URL = entry.url; result.push(newAccount); } aListener.onSuccess(new simpleEnumerator(result), null); }, onError: function(errorcode, errormsg) { svc.logger.error("<<<<<<<<<< Metaweblog API: SERVER TO FLOCK\n"); svc.logger.error("ERROR "+errorcode+" "+errormsg+"\n"); var error = Cc['@flock.com/error;1'].createInstance(Ci.flockIError); error.serviceErrorCode = errorcode; error.serviceErrorString = errormsg; aListener.onError(null, "", error); }, onFault: function(errorcode, errormsg) { svc.logger.error("<<<<<<<<<< Metaweblog API: SERVER TO FLOCK\n"); svc.logger.error("FAULT "+errorcode+" "+errormsg+"\n"); var error = Cc['@flock.com/error;1'].createInstance(Ci.flockIError); error.serviceErrorCode = errorcode; error.serviceErrorString = errormsg; switch (errorcode) { case 403: // Invalid login/pass case 801: // At least dotclear uses code 801 for bad auth error.errorCode = Ci.flockIError.BLOG_INVALID_AUTH; error.errorString = "Bad authentication"; break; default: // Unknown error code error.errorCode = Ci.flockIError.BLOG_UNKNOWN; error.errorString = "Unknown Error"; } aListener.onError(null, "", error); } } var xmlrpcServer = new flockXmlRpcServer (aAccount.apiLink); var args = [this.appKey, aAccount.username, aAccount.password]; xmlrpcServer.call("blogger.getUsersBlogs", args, listener); } metaweblogWebService.prototype.getRecentPosts = function(aListener, aBlogId, aNumber){ var gBlogService = Cc['@flock.com/flock-blog;1'].getService(Ci.flockIBlogService); var account = gBlogService.getAccount(aBlogId); var listener = { onResult: function(aResult) { var result = new Array(); // svc.logger.info("<<<<<<<<<< MetaWeblog API: SERVER TO FLOCK\n"); for (i=0; i<aResult.length; i++) { var post = new BlogPost(); post.title = aResult[i].title; post.issued = aResult[i].dateCreated.getTime(); post.postid = aResult[i].postid; result.push(post); } // and return the data source through the listener aListener.onResult(new simpleEnumerator(result)); }, onError: function(error) { //svc.logger.error("<<<<<<<<<< MetaWeblog API: SERVER TO FLOCK\n"); //svc.logger.error("ERROR "+error+"\n"); aListener.onError(error); }, onFault: function(error) { //svc.logger.error("<<<<<<<<<< MetaWeblog API: SERVER TO FLOCK\n"); //svc.logger.error("FAULT "+error+"\n"); aListener.onFault(error); } } var xmlrpcServer = new flockXmlRpcServer (account.apiLink); var args = [account.blogid, account.username, account.password, aNumber]; xmlrpcServer.call("metaWeblog.getRecentPosts", args, listener); } metaweblogWebService.prototype.getCategoryList = function(aListener, aBlogId){ var gBlogService = Cc['@flock.com/flock-blog;1'].getService(Ci.flockIBlogService); var account = gBlogService.getAccount(aBlogId); var svc = this; var listener = new blogCategoryListener(aListener, false); var xmlrpcServer = new flockXmlRpcServer (account.apiLink); var args = [account.blogid, account.username, account.password]; xmlrpcServer.call("metaWeblog.getCategories", args, listener); } metaweblogWebService.prototype.removeAccount = function (aId) { if (!this.logger) this.setup(); var faves_coop = Cc['@flock.com/singleton;1'].getService(Ci.flockISingleton).getSingleton('chrome://browser/content/flock/common/load-faves-coop.js').wrappedJSObject; var acUtils = Cc["@flock.com/account-utils;1"].getService(Ci.flockIAccountUtils); var pm = Cc["@mozilla.org/passwordmanager;1"].getService(Ci.nsIPasswordManager); var account = faves_coop.get(aId); this.logger.debug("REMOVE: "+aId+" - "+account.accountId); // Remove the password try { pm.removeUser(aId, account.accountId); } catch(e) { this.logger.warn("Exception trying to remove the password. It may have been already deleted."); } // Destroy the blogs and the account var _enum = account.children.enumerate(); while (_enum.hasMoreElements()) { var blog = _enum.getNext(); account.children.remove(blog); blog.destroy(); } account.destroy(); } // That a bit hacky, a way to not break flockAccountUtils.removeAllAccounts metaweblogWebService.prototype.getAccount = function (aId) { return { logout: function(aArg) { return; }, getInterfaces: function (count) { var interfaceList = [Ci.nsISupports, Ci.flockIWebServiceAccount, Ci.flockIBlogWebServiceAccount]; count.value = interfaceList.length; return interfaceList; }, QueryInterface: function (iid) { if (!iid.equals(Ci.nsISupports) && !iid.equals(Ci.flockIWebServiceAccount) && !iid.equals(Ci.flockIBlogWebServiceAccount)) { throw Components.results.NS_ERROR_NO_INTERFACE; } return this; } } } metaweblogWebService.prototype.flags = Ci.nsIClassInfo.SINGLETON; metaweblogWebService.prototype.contractID = FLOCK_MW_CONTRACTID; metaweblogWebService.prototype.classDescription = "Flock Metaweblog API Service"; metaweblogWebService.prototype.getInterfaces = function (count) { var interfaceList = [Ci.flockIWebService, Ci.flockICustomBlogWebService, Ci.flockIBlogWebService, Ci.nsIClassInfo, Ci.nsISupports]; count.value = interfaceList.length; return interfaceList; } metaweblogWebService.prototype.getHelperForLanguage = function (count) {return null;} // Module implementation var MetaweblogModule = new Object(); MetaweblogModule.registerSelf = function (compMgr, fileSpec, location, type) { compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar); compMgr.registerFactoryLocation(FLOCK_MW_CID, "Flock MetaWeblog JS Component", FLOCK_MW_CONTRACTID, fileSpec, location, type); //necessary category registration var catmgr = Components.classes["@mozilla.org/categorymanager;1"] .getService (Components.interfaces.nsICategoryManager); catmgr.addCategoryEntry('flockICustomBlogWebService', 'metaweblog', FLOCK_MW_CONTRACTID, true, true); } MetaweblogModule.getClassObject = function (compMgr, cid, iid) { if (!cid.equals(FLOCK_MW_CID)) throw Components.results.NS_ERROR_NO_INTERFACE; if (!iid.equals(Components.interfaces.nsIFactory)) throw Components.results.NS_ERROR_NOT_IMPLEMENTED; return MetaweblogServiceFactory; } MetaweblogModule.canUnload = function(compMgr) { return true; } // factory object var MetaweblogServiceFactory = new Object(); MetaweblogServiceFactory.createInstance = function (outer, iid) { if (outer != null) throw Components.results.NS_ERROR_NO_AGGREGATION; return (new metaweblogWebService()).QueryInterface(iid); } /* entrypoint */ function NSGetModule(compMgr, fileSpec) { return MetaweblogModule; }